package com.torry.workflow.service.user.facade;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.torry.workflow.api.user.api.PermApi;
import com.torry.workflow.api.user.entity.*;
import com.torry.workflow.common.exception.BizException;
import com.torry.workflow.service.user.service.IPermService;
import com.torry.workflow.service.user.service.IRolePermService;
import com.torry.workflow.service.user.service.IRoleService;
import com.torry.workflow.service.user.service.IUserRoleService;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@DubboService
@Component
public class PermFacade implements PermApi {

    @Resource
    private IPermService iPermService;
    @Resource
    private IUserRoleService iUserRoleService;
    @Resource
    private IRoleService iRoleService;
    @Resource
    private IRolePermService iRolePermService;

    @Override
    public List<Perm> allPerms() {
        return iPermService.list(new QueryWrapper<Perm>().eq("deleted", 0));
    }

    @Override
    @Transactional
    public void savePerm(Perm perm) {
        if (permIsExist(perm)) {
            throw new BizException(400, "权限名称或Code已经存在");
        }
        iPermService.saveOrUpdate(perm);
    }

    private boolean permIsExist(Perm perm) {
        Perm permInfoByName = iPermService.getOne(new QueryWrapper<Perm>().eq("deleted", 0)
                .eq("name", perm.getName()));

        Perm permInfoByCode = iPermService.getOne(new QueryWrapper<Perm>().eq("deleted", 0)
                .eq("code", perm.getCode()));
        if (perm.getId() == null) {
            return permInfoByName != null || permInfoByCode != null;
        }
        return (permInfoByName != null && !perm.getId().equals(permInfoByName.getId()))
                ||
                (permInfoByCode != null && !perm.getId().equals(permInfoByCode.getId()));
    }

    @Override
    public List<Perm> getPermsByUserId(Integer userId) {
        List<Integer> roleIds = iRoleService.getRoleIdsByUserId(userId);
        if (CollectionUtils.isNotEmpty(roleIds)) {
            List<Integer> permIdList = new ArrayList<>();
            roleIds.forEach(roleId -> {
                List<Integer> permIds = iRolePermService.listObjs(new QueryWrapper<RolePerm>().select("perm_id").eq("deleted", 0).eq("role_id", roleId),
                        (menuId) -> Integer.parseInt(menuId.toString()));
                permIdList.addAll(permIds);
            });
            if (CollectionUtils.isNotEmpty(permIdList)) {
                List<Perm> perms = iPermService.list(new QueryWrapper<Perm>().eq("deleted", 0).in("id", permIdList));
                if (CollectionUtils.isNotEmpty(perms)) {
                    return perms;
                }
            }

        }
        return new ArrayList<>();
    }


    @Override
    public List<Perm> getPermsByRoleId(Integer roleId) {

        List<Integer> permIds = iRolePermService.listObjs(new QueryWrapper<RolePerm>()
                        .select("perm_id").eq("deleted", 0)
                        .eq("role_id", roleId),
                (menuId) -> Integer.parseInt(menuId.toString()));

        if (CollectionUtils.isNotEmpty(permIds)) {
            List<Perm> perms = iPermService.list(new QueryWrapper<Perm>().eq("deleted", 0).in("id", permIds));
            if (CollectionUtils.isNotEmpty(perms)) {
                return perms;
            }
        }
        return new ArrayList<>();
    }

    @Override
    @Transactional
    public void deletePermByIds(List<Integer> ids) {
        iPermService.update(new UpdateWrapper<Perm>().set("deleted", 1).in("id", ids));
        iRolePermService.update(new UpdateWrapper<RolePerm>().set("deleted", 1).in("perm_id", ids));
    }
}
